package com.youths.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.gson.Gson;
import com.youths.domain.*;
import com.youths.response.Result;
import com.youths.service.*;
import com.youths.util.HttpAPIUtil;
import com.youths.util.StringUtil;
import javafx.geometry.Pos;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpSession;
import java.util.*;
import java.util.concurrent.ExecutionException;

/**
 * Created by IntelliJ IDEA.
 * User: KingRainGrey
 * Date: 2020/7/14
 */
@Controller
@RequestMapping(value = "/")
public class VerifyController {
    @Autowired
    TaskService taskService;
    @Autowired
    SliceService sliceService;
    @Autowired
    YouthInfoService youthInfoService;
    @Autowired
    RecognizationService recognizationService;
    @Autowired
    ScoreService scoreService;
    @Autowired
    HeightInfoService heightInfoService;

    @Autowired
    HttpAPIUtil httpAPIUtil;


    @Value("${url.heightplot}")
    String heightPlotUrl;

    @Value("${url.calculate}")
    String rankCalculateUrl;


    @GetMapping(value = "rank")
    public String rank(String taskStr,
                       HttpSession session,
                       Model model) {
        try {
            if (check(session)) {
                Integer taskId = StringUtil.decrypt(taskStr);
                Integer sliceId = taskService.querySliceId(taskId);
                Slice slice = sliceService.query(sliceId);
                List<Recognization> recognizations = recognizationService.getRecogList(sliceId);
                if (recognizations.size() > 0) {
                    Recognization recognization = recognizations.get(0);// chn
                    Score score = scoreService.queryScore(recognization.getRecoId());
                    model.addAttribute("score", score);
                    model.addAttribute("recog", recognization);
                    model.addAttribute("taskStr", taskStr);
                    model.addAttribute("url", slice.getHttpPath());
                }
                return "analysis/rank";
            }
        }catch (Exception e) {
            e.printStackTrace();
        }
        model.addAttribute("msg", "没有权限");
        return "login";
    }

    @GetMapping(value = "modify")
    public String modify(String taskStr,
                         HttpSession session,
                         Model model) {
        try {
            if (check(session)) {
                Integer taskId = StringUtil.decrypt(taskStr);
                Integer sliceId = taskService.querySliceId(taskId);
                Slice slice = sliceService.query(sliceId);
                List<Recognization> recognizations = recognizationService.getRecogList(sliceId);
                for (Recognization recognization:recognizations) {
                    if (recognization.getKind() == 1) {//ai
                        Score aiScore = scoreService.queryScore(recognization.getRecoId());
                        model.addAttribute("aiRecog", recognization);
                        model.addAttribute("aiScore", aiScore);
                        model.addAttribute("url", slice.getHttpPath());
                    }
                    if (recognization.getKind() == 2) {//expert
                        Score expertScore = scoreService.queryScore(recognization.getRecoId());
                        model.addAttribute("exRecog", recognization);
                        model.addAttribute("exScore", expertScore);
                        model.addAttribute("exRecogIdStr", StringUtil.encryption(recognization.getRecoId()));
                        model.addAttribute("url", slice.getHttpPath());
                    }
                }
                model.addAttribute("taskStr", taskStr);
                return "analysis/modify";
            }
        }catch (Exception e) {
            e.printStackTrace();
        }
        model.addAttribute("msg", "没有权限");
        return "login";
    }


    @GetMapping(value = "getVerifyList")
    @ResponseBody
    public ReturnData<ReturnVerify> getVerifyList(Task task, HttpSession session) {
        try {
            if (check(session)) {
                LabelConsumer consumer = (LabelConsumer) session.getAttribute("user");
                task.setState(1);
                task.setExpertId(consumer.getConsumerId());
                ReturnData<ReturnVerify> verifyList = new ReturnData<>();
                int nums = taskService.getTotal(1, consumer.getConsumerId());
                verifyList.setTotal(nums);
                List<Task> tasks = taskService.getAll(task);
                List<ReturnVerify> verifies = new ArrayList<>();
                for (Task t:tasks) {
                    ReturnVerify verify = new ReturnVerify();
                    verify.setTaskId(t.getTaskId());
                    verify.setTaskStr(t.getTaskId());
                    verify.setSliceStr(t.getSlicingId());
                    verify.setCreateTime(t.getCreateTime());
                    Slice slice = sliceService.query(t.getSlicingId());
                    YouthInfo youthInfo = youthInfoService.queryYouthInfo(slice.getYouthId());
                    verify.setAge(youthInfo.getYouthBirth(), slice.getPhysicalTime());
                    verify.setHeight(slice.getHeight());
                    verify.setWeight(slice.getWeight());
                    verifies.add(verify);
                }
                verifyList.setRows(verifies);
                return verifyList;
            }
        }catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @GetMapping(value = "recordList")
    @ResponseBody
    public ReturnData<Record> record(Task task, HttpSession session) {
        try {
            LabelConsumer consumer = (LabelConsumer) session.getAttribute("user");
            if (consumer != null) {
                Integer expertId = consumer.getConsumerId();
                int nums = taskService.getRecordNum(expertId);

                ReturnData<Record> recordList = new ReturnData<>();
                recordList.setTotal(nums);

                task.setExpertId(expertId);
                List<Task> tasks = taskService.getRecords(task);
                List<Record> records = new ArrayList<>();
                for (Task t:tasks) {
                    Record record = new Record();
                    record.setRecordId(t.getTaskId());
                    record.setTaskStr(t.getTaskId());
                    record.setAddTime(t.getCreateTime());
                    record.setDoneTime(t.getUpdateTime());
                    Slice slice = sliceService.query(t.getSlicingId());
                    record.setSliceStr(slice.getSlicingId());
                    record.setState(slice.getState());
                    record.setStateStr(slice.getState());
                    records.add(record);
                }
                recordList.setRows(records);
                return recordList;
            }
        }catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }


    @GetMapping(value = "verifyList")
    public String verifyList(HttpSession session, Model model) {
        if (check(session)) {
            return "/expert/verifyList";
        }else {
            model.addAttribute("msg", "没有权限");
            return "/login";
        }
    }

    @PostMapping(value = "submit")
    @ResponseBody
    @Transactional
    public String submit(@RequestParam("sliceStr") String sliceStr, HttpSession session) {
        Gson gson = new Gson();
        Map<String, Object> res = new HashMap<>();
        try {
            int sliceId = StringUtil.decrypt(sliceStr);
            Slice slice = sliceService.query(sliceId);
            if (slice != null) {
                if (slice.getState() == 2) {
                    Task task = new Task();
                    task.setSlicingId(sliceId);
                    task.setState(0);
                    int result = taskService.addTask(task);
                    if (result > 0) {
                        int updateTag = sliceService.updateState(sliceId, 3);
                        if (updateTag > 0) {
                            res.put("code", 1);
                            res.put("msg", "提交审核成功");
                        }else {
                            res.put("code", 0);
                            res.put("msg", "状态更新失败");
                        }
                    }else {
                        res.put("code", 0);
                        res.put("msg", "提交审核失败");
                    }
                }else {
                    res.put("code", 0);
                    res.put("msg", "已提交审核");
                }
            }
        }catch (Exception e) {
            e.printStackTrace();
            res.put("code", 0);
            res.put("msg", e.getMessage());
        }
        return gson.toJson(res);
    }

    @PostMapping(value = "submitNewRank",produces = {"application/json;charset=UTF-8"})
    @ResponseBody
    @Transactional
    public String submitNewRank(String recog,
                                String taskStr,
                                HttpSession session) {
        Gson gson = new Gson();
        Map<String,Object> result = new HashMap<>();
        try{
            if (check(session)) {
                LabelConsumer consumer = (LabelConsumer) session.getAttribute("user");
                int consumerId = consumer!=null?consumer.getConsumerId():null;
                Integer taskId = StringUtil.decrypt(taskStr);
                Recognization recognization = JSON.parseObject(recog, Recognization.class);
                int sliceId = taskService.querySliceId(taskId);
                Slice slice = sliceService.query(sliceId);
                recognization.setSlicingId(slice.getSlicingId());
                recognization.setState(0);
                recognization.setKind(2);
                int recoId = recognizationService.add(recognization);
                if (recoId > 0) {
                    int youthId = slice.getYouthId();
                    YouthInfo youthInfo = youthInfoService.queryYouthInfo(youthId);
                    Map<String, Object> param = new HashMap<>();
                    param.put("age", StringUtil.getAge(youthInfo.getYouthBirth(),slice.getPhysicalTime()));
                    param.put("sex", youthInfo.getYouthSex());
                    param.put("rao", recognization.getRaoScore());
                    param.put("gou", recognization.getGouScore());
                    param.put("tou", recognization.getTouScore());
                    param.put("chi", recognization.getChiScore());
                    param.put("zhang1", recognization.getZhang1Score());
                    param.put("zhang3", recognization.getZhang3Score());
                    param.put("zhang5", recognization.getZhang5Score());
                    param.put("jin1", recognization.getJin1Score());
                    param.put("jin3", recognization.getJin3Score());
                    param.put("jin5", recognization.getJin5Score());
                    param.put("zhong3", recognization.getZhang3Score());
                    param.put("zhong5", recognization.getZhang5Score());
                    param.put("yuan1", recognization.getYuan1Score());
                    param.put("yuan3", recognization.getYuan3Score());
                    param.put("yuan5", recognization.getYuan5Score());
                    HttpResult httpResult = httpAPIUtil.doGet(rankCalculateUrl, param);
                    if (httpResult.getCode() == 200) {
                        RecoEntity recoEntity = JSON.parseObject(httpResult.getBody(), RecoEntity.class);
                        if (recoEntity.getCode().equals("success")) {
                            Score score = new Score();
                            score.setRecoId(recoId);
                            score.setChnBoneage(recoEntity.getData().getChn_boneage());
                            score.setTw3Boneage(recoEntity.getData().getTw3_boneage());
                            score.setTwcBoneage(recoEntity.getData().getTwc_boneage());
                            score.setSituation(recoEntity.getData().getSituation());
                            score.setState(0);
                            int scoreId = scoreService.addScore(score);
                            if (scoreId > 0) {
                                //todo
                                Map<String, Object> heightParam = new HashMap<>();
                                heightParam.put("age", StringUtil.getAge(youthInfo.getYouthBirth(), slice.getPhysicalTime()));
                                heightParam.put("boneage", recoEntity.getData().getChn_boneage());
                                String sexArray[] = {"男", "女"};
                                heightParam.put("sex", sexArray[youthInfo.getYouthSex()]);
                                heightParam.put("height",slice.getHeight());
                                heightParam.put("yichuanx", youthInfo.getYouthMotherHeight());
                                heightParam.put("yichuany", youthInfo.getYouthFatherHeight());
                                HttpResult heightResult = httpAPIUtil.doGet(heightPlotUrl, heightParam);
                                if (heightResult.getCode() == 200) {
                                    HeightEntity heightEntity = JSON.parseObject(heightResult.getBody(), HeightEntity.class);
                                    HeightInfo heightInfo = new HeightInfo();
                                    heightInfo.setRecoId(recoId);
                                    heightInfo.setBpForecastHeight(heightEntity.getBp());
                                    heightInfo.setImproveBpForecastHeight(heightEntity.getBp2());
                                    heightInfo.setGeneticHeight(heightEntity.getTarget());
                                    heightInfo.setGrowthTrend(StringUtil.jsonArrayToString(heightEntity.getForecast()));
                                    heightInfo.setEvaluate(heightEntity.getMessage());
                                    heightInfo.setState(0);
                                    int heightId = heightInfoService.addHeightInfo(heightInfo);
                                    if (heightId > 0) {
                                        //更新slice-状态-专家等级录入
                                        int updateCode = sliceService.updateState(sliceId, 4);
                                        if (updateCode > 0) {
                                            //更新task expertId taskId
                                            int updateTask = taskService.updateTaskState(consumerId, 1, taskId);
                                            if (updateTask > 0) {
                                                result.put("code", 1);
                                                result.put("msg", "提交成功");
                                                result.put("sliceStr", StringUtil.encryption(sliceId));
                                                return gson.toJson(result);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }catch (Exception e) {
            e.printStackTrace();
        }
        result.put("code", 0);
        result.put("msg","提交失败");
        return gson.toJson(result);
    }

    @PostMapping(value = "updateNewRank",produces = {"application/json;charset=UTF-8"})
    @ResponseBody
    @Transactional
    public String updateNewRank(String recog,
                                String recogStr,
                                String taskStr,
                                HttpSession session) {
        Gson gson = new Gson();
        Map<String, Object> result = new HashMap<>();
        try {
            if (check(session)) {
                LabelConsumer consumer = (LabelConsumer) session.getAttribute("user");
                int consumerId = consumer!=null?consumer.getConsumerId():null;
                Integer taskId = StringUtil.decrypt(taskStr);
                Integer sliceId = taskService.querySliceId(taskId);
                Integer recogId = StringUtil.decrypt(recogStr);
                Recognization oldRecog = recognizationService.query(recogId);
                Recognization newRecog = JSON.parseObject(recog, Recognization.class);
                BeanUtil.copyProperties(newRecog, oldRecog, CopyOptions.create().setIgnoreNullValue(true));
                oldRecog.setState(1);
                int updateCode = recognizationService.updateRank(oldRecog);
                if (updateCode > 0) {
                    //update score
                    Slice slice = sliceService.query(sliceId);
                    YouthInfo youthInfo = youthInfoService.queryYouthInfo(slice.getYouthId());
                    Map<String, Object> param = new HashMap<>();
                    param.put("age", StringUtil.getAge(youthInfo.getYouthBirth(),slice.getPhysicalTime()));
                    param.put("sex", youthInfo.getYouthSex());
                    param.put("rao", newRecog.getRaoScore());
                    param.put("gou", newRecog.getGouScore());
                    param.put("tou", newRecog.getTouScore());
                    param.put("chi", newRecog.getChiScore());
                    param.put("zhang1", newRecog.getZhang1Score());
                    param.put("zhang3", newRecog.getZhang3Score());
                    param.put("zhang5", newRecog.getZhang5Score());
                    param.put("jin1", newRecog.getJin1Score());
                    param.put("jin3", newRecog.getJin3Score());
                    param.put("jin5", newRecog.getJin5Score());
                    param.put("zhong3", newRecog.getZhang3Score());
                    param.put("zhong5", newRecog.getZhang5Score());
                    param.put("yuan1", newRecog.getYuan1Score());
                    param.put("yuan3", newRecog.getYuan3Score());
                    param.put("yuan5", newRecog.getYuan5Score());
                    HttpResult httpResult = httpAPIUtil.doGet(rankCalculateUrl, param);
                    if (httpResult.getCode() == 200) {
                        RecoEntity recoEntity = JSON.parseObject(httpResult.getBody(), RecoEntity.class);
                        if (recoEntity.getCode().equals("success")) {
                            Score score = scoreService.queryScore(recogId);
                            score.setChnBoneage(recoEntity.getData().getChn_boneage());
                            score.setTw3Boneage(recoEntity.getData().getTw3_boneage());
                            score.setTwcBoneage(recoEntity.getData().getTwc_boneage());
                            score.setSituation(recoEntity.getData().getSituation());

                            score.setState(1);
                            int scoreUpdateCode = scoreService.updateBoneage(score);
                            if (scoreUpdateCode > 0) {
                                //update height info
                                Map<String, Object> heightParam = new HashMap<>();
                                heightParam.put("age", StringUtil.getAge(youthInfo.getYouthBirth(),slice.getPhysicalTime()));
                                heightParam.put("boneage", recoEntity.getData().getChn_boneage());
                                String sexArray[] = {"男", "女"};
                                heightParam.put("sex", sexArray[youthInfo.getYouthSex()]);
                                heightParam.put("height",slice.getHeight());
                                heightParam.put("yichuanx", youthInfo.getYouthMotherHeight());
                                heightParam.put("yichuany", youthInfo.getYouthFatherHeight());
                                HttpResult heightResult = httpAPIUtil.doGet(heightPlotUrl, heightParam);
                                if (heightResult.getCode() == 200) {
                                    HeightEntity heightEntity = JSON.parseObject(heightResult.getBody(), HeightEntity.class);
                                    HeightInfo heightInfo = heightInfoService.query(recogId);
                                    heightInfo.setBpForecastHeight(heightEntity.getBp());
                                    heightInfo.setImproveBpForecastHeight(heightEntity.getBp2());
                                    heightInfo.setGeneticHeight(heightEntity.getTarget());
                                    heightInfo.setGrowthTrend(StringUtil.jsonArrayToString(heightEntity.getForecast()));
                                    heightInfo.setEvaluate(heightEntity.getMessage());
                                    heightInfo.setState(1);
                                    int heightInfoUpdateCode = heightInfoService.updateHeightInfo(heightInfo);
                                    if (heightInfoUpdateCode > 0) {

                                        result.put("code", 1);
                                        result.put("msg","提交成功");
                                        result.put("sliceStr", StringUtil.encryption(sliceId));
                                        return gson.toJson(result);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }catch (Exception e) {
            e.printStackTrace();
        }
        result.put("code", 0);
        result.put("msg","提交失败");
        return gson.toJson(result);
    }


    @PostMapping(value = "calculate",produces = {"application/json;charset=UTF-8"})
    @ResponseBody
    public String calculate(String recog, String taskStr) {
        Gson gson = new Gson();
        Map<String, Object> map = new HashMap<>();
        try {
            Integer taskId = StringUtil.decrypt(taskStr);
            Recognization recognization = JSON.parseObject(recog, Recognization.class);
            int sliceId = taskService.querySliceId(taskId);
            Slice slice = sliceService.query(sliceId);
            int youthId = slice.getYouthId();
            YouthInfo youthInfo = youthInfoService.queryYouthInfo(youthId);
            Map<String, Object> param = new HashMap<>();
            param.put("age", StringUtil.getAge(youthInfo.getYouthBirth(),slice.getPhysicalTime()));
            param.put("sex", youthInfo.getYouthSex());
            param.put("rao", recognization.getRaoScore());
            param.put("gou", recognization.getGouScore());
            param.put("tou", recognization.getTouScore());
            param.put("chi", recognization.getChiScore());
            param.put("zhang1", recognization.getZhang1Score());
            param.put("zhang3", recognization.getZhang3Score());
            param.put("zhang5", recognization.getZhang5Score());
            param.put("jin1", recognization.getJin1Score());
            param.put("jin3", recognization.getJin3Score());
            param.put("jin5", recognization.getJin5Score());
            param.put("zhong3", recognization.getZhang3Score());
            param.put("zhong5", recognization.getZhang5Score());
            param.put("yuan1", recognization.getYuan1Score());
            param.put("yuan3", recognization.getYuan3Score());
            param.put("yuan5", recognization.getYuan5Score());
            HttpResult httpResult = httpAPIUtil.doGet(rankCalculateUrl, param);
            if (httpResult.getCode() == 200) {
                RecoEntity recoEntity = JSON.parseObject(httpResult.getBody(), RecoEntity.class);
                if (recoEntity.getCode().equals("success")) {
                    map.put("code", 1);
                    map.put("msg", "计算成功");
                    map.put("chn", recoEntity.getData().getChn_boneage());
                    map.put("tw3", recoEntity.getData().getTw3_boneage());
                    map.put("twc", recoEntity.getData().getTwc_boneage());
                    return gson.toJson(map);
                }
            }
        }catch (Exception e) {
            e.printStackTrace();
        }
        map.put("code", 0);
        map.put("msg", "计算失败");
        return gson.toJson(map);
    }


    @PostMapping(value = "addSuggestion",produces = {"application/json;charset=UTF-8"})
    @ResponseBody
    public String addSuggestion(String text, String recogStr, String sliceStr) {
        Gson gson = new Gson();
        Map<String, Object> result = new HashMap<>();
        try {
            int sliceId = StringUtil.decrypt(sliceStr);
            int taskId = taskService.queryTaskId(sliceId);
            //System.out.println("" + StringUtil.decrypt(recogStr));
            Score score = scoreService.queryScore(StringUtil.decrypt(recogStr));
            if (score != null) {
                //System.out.println("text" + text);
                //add text update state
                int scoreUpdate = scoreService.update(score.getScoreId(), text!=null?text.trim():text, 1);
                if (scoreUpdate > 0) {
                    int updateSlice = sliceService.updateState(sliceId, 5);
                    int taskUpdate = taskService.updateState(2, taskId);
                    if (updateSlice > 0 && taskUpdate > 0) {
                        result.put("code",1);
                        result.put("msg","提交成功");
                        return gson.toJson(result);
                    }
                }
            }

        }catch (Exception e){
            e.printStackTrace();
        }
        result.put("code",0);
        result.put("msg","提交失败");
        return gson.toJson(result);
    }

    @PostMapping(value = "updateSuggestion",produces = {"application/json;charset=UTF-8"})
    @ResponseBody
    public String updateSuggestion(String text, String recogStr) {
        Gson gson = new Gson();
        Map<String, Object> result = new HashMap<>();
        try {
            Score score = scoreService.queryScore(StringUtil.decrypt(recogStr));
            if (score != null) {
                int scoreUpdate = scoreService.update(score.getScoreId(), text!=null?text.trim():text, 1);
                if (scoreUpdate > 0) {
                    result.put("code",1);
                    result.put("msg","更新成功");
                    return gson.toJson(result);
                }
            }

        }catch (Exception e){
            e.printStackTrace();
        }
        result.put("code",0);
        result.put("msg","更新失败");
        return gson.toJson(result);
    }

    @GetMapping(value = "verifyRecord")
    public String verifyRecord(HttpSession session, Model model) {
        if (check(session)) {
            return "/expert/expertRecord";
        }else {
            model.addAttribute("msg", "没有权限");
            return "/login";
        }
    }


    private boolean check(HttpSession session) {
        LabelConsumer consumer = (LabelConsumer) session.getAttribute("user");
        if (consumer != null) {
            if (consumer.getKind() == 1) {
                return true;
            }
        }
        return false;
    }

    @GetMapping("/back/getTaskList")
    @ResponseBody
    public Result getTaskList(@RequestParam("pageNum") Integer pageNum,
                              @RequestParam("pageSize") Integer pageSize,
                              @RequestParam("slicingId") Integer slicingId,
                              @RequestParam("expertId") Integer expertId,
                              @RequestParam("card") String card,
                              @RequestParam("name") String name,
                              @RequestParam("state") Integer state,
                              @RequestParam("order") String order){
        return Result.success(taskService.getTaskList(pageNum,pageSize,slicingId,expertId,card,name,state,order));
    }

    @PostMapping("/back/taskDistribution")
    @ResponseBody
    public Result taskDistribution(@RequestParam("expertId") Integer expertId,
                                   @RequestParam("taskId") String taskId){
        return Result.success(taskService.taskDistribution(expertId,taskId));
    }

    @PostMapping("/back/cancelTask")
    @ResponseBody
    public Result cancelTask(@RequestParam("taskId") String taskId){
        return Result.success(taskService.cancelTask(taskId));
    }
}
